fix: replace az CLI token acquisition with MSAL.NET to eliminate proy resets#324
Merged
sellakumaran merged 3 commits intomainfrom Mar 27, 2026
Merged
Conversation
…y resets (#321) Users on corporate networks with TLS inspection proxies intermittently saw ConnectionResetError (10054) during 'a365 setup all'. The failure was non-deterministic — different steps each run, restarting sometimes helped. Root cause: all token acquisition called 'az account get-access-token' as a subprocess. The Azure CLI is Python-based and uses an HTTP connection pool that the TLS proxy would reset mid-execution during longer commands. Fix: replaced all subprocess token acquisition with direct MSAL.NET calls via AuthenticationService. On Windows, MSAL uses WAM — an OS-level broker that communicates over IPC, bypassing the proxy entirely. On macOS/Linux, MSAL uses browser or device code flow. Changes: - GraphApiService and ArmApiService now acquire tokens via IAuthenticationService (MSAL) instead of spawning 'az account get-access-token' subprocesses - AzCliHelper retains only login-hint resolution (az account show); token acquisition methods removed - BotConfigurator reads tenantId from config instead of 'az account show' - NetworkHelper centralises connection-reset detection and warning message - RetryHelper accepts constructor-level defaults; injectable in tests to skip backoff delays - AuthenticationService gains ResolveLoginHintFromCacheAsync as fallback when az CLI is not available - Added tests for ResolveLoginHintFromCacheAsync and NetworkHelper
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Snapshot WarningsEnsure that dependencies are being submitted on PR branches and consider enabling retry-on-snapshot-warnings. See the documentation for more information and troubleshooting advice. Scanned FilesNone |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR replaces Azure CLI subprocess-based token acquisition (az account get-access-token) with MSAL.NET-based acquisition via AuthenticationService, and adds connection-reset diagnostics/retry behavior intended to mitigate intermittent proxy/TLS inspection resets during a365 setup all and related flows.
Changes:
- Introduces
IAuthenticationServiceand updates Graph/ARM services and tests to use MSAL-based token acquisition instead of Azure CLI token calls. - Adds
NetworkHelperfor connection-reset detection and integratesRetryHelperinto selected HTTP paths. - Updates setup/bot flows and docs/changelog to reflect the new authentication and resilience architecture.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/Helpers/NetworkHelperTests.cs | Adds unit tests for connection-reset detection. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/Helpers/AzCliHelperTests.cs | Removes Azure CLI token cache tests; keeps login-hint cache tests. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceVerifyInheritablePermissionsTests.cs | Updates GraphApiService construction to inject auth service. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceTokenTrimTests.cs | Updates token trimming tests to use IAuthenticationService stubs. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceTokenCacheTests.cs | Removes tests tied to the old AzCliHelper token cache behavior. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceTests.cs | Updates GraphApiService tests to use IAuthenticationService and retry helper injection. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceIsApplicationOwnerTests.cs | Updates tests away from az CLI token mocking to IAuthenticationService. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/GraphApiServiceAddRequiredResourceAccessTests.cs | Updates blueprint permission tests to inject IAuthenticationService. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/ClientAppValidatorTests.cs | Adjusts imports for updated validator dependencies. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/AuthenticationServiceTests.cs | Adds tests for ResolveLoginHintFromCacheAsync. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/ArmApiServiceTests.cs | Updates ARM tests to inject IAuthenticationService and retry helper. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/AgentBlueprintServiceTests.cs | Updates GraphApiService construction to include auth service. |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/CleanupCommandTests.cs | Updates GraphApiService construction signature (auth service param). |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/CleanupCommandBotEndpointTests.cs | Updates GraphApiService construction signature (auth service param). |
| src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/BlueprintSubcommandTests.cs | Simplifies GraphApiService partial substitute construction after signature change. |
| src/Microsoft.Agents.A365.DevTools.Cli/design.md | Documents MSAL-based authentication architecture and caching behavior. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/Helpers/RetryHelper.cs | Makes retry parameters configurable via ctor/defaults; supports overrides per call. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/Helpers/NetworkHelper.cs | Adds shared connection-reset detection and warning message. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/Helpers/AzCliHelper.cs | Removes token acquisition; retains login-hint resolution via az account show. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/GraphApiService.cs | Switches token acquisition to IAuthenticationService; adds retry + proxy-reset diagnostics in some paths. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/DelegatedConsentService.cs | Updates fresh-token acquisition to use GraphApiService/MSAL path. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/ClientAppValidator.cs | Removes AzCli token cache invalidation; retries on 401. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/BotConfigurator.cs | Reads tenantId from config; resolves login hint via az CLI or MSAL cache. |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/AuthenticationService.cs | Introduces IAuthenticationService and adds ResolveLoginHintFromCacheAsync (JWT decode). |
| src/Microsoft.Agents.A365.DevTools.Cli/Services/ArmApiService.cs | Switches ARM token acquisition to MSAL (IAuthenticationService) and wraps GETs with retry helper. |
| src/Microsoft.Agents.A365.DevTools.Cli/Program.cs | Registers IAuthenticationService in DI backed by AuthenticationService. |
| src/Microsoft.Agents.A365.DevTools.Cli/Commands/SetupSubcommands/InfrastructureSubcommand.cs | Removes eager ARM token prefetch; defers to ARM service lazy acquisition. |
| src/Microsoft.Agents.A365.DevTools.Cli/Commands/SetupSubcommands/BlueprintSubcommand.cs | Constructs delegated-consent GraphApiService with MSAL-based auth service. |
| CHANGELOG.md | Adds entry for fixing intermittent connection reset failures (#321). |
src/Microsoft.Agents.A365.DevTools.Cli/Services/ClientAppValidator.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Agents.A365.DevTools.Cli/Services/GraphApiService.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Agents.A365.DevTools.Cli/Services/GraphApiService.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Agents.A365.DevTools.Cli/Services/GraphApiService.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.Agents.A365.DevTools.Cli/Services/AuthenticationService.cs
Show resolved
Hide resolved
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Services/AuthenticationServiceTests.cs
Outdated
Show resolved
Hide resolved
ajmfehr
previously approved these changes
Mar 27, 2026
gwharris7
reviewed
Mar 27, 2026
src/Tests/Microsoft.Agents.A365.DevTools.Cli.Tests/Commands/BlueprintSubcommandTests.cs
Show resolved
Hide resolved
Add forceRefresh to Graph token flow; improve testability Introduce a forceRefresh parameter to Microsoft Graph token acquisition, allowing explicit cache bypass and fresh token retrieval. Update IMicrosoftGraphTokenProvider and MicrosoftGraphTokenProvider to support this, and refactor GraphApiService to propagate forceRefresh throughout token and header acquisition. Update all call sites to use named arguments for clarity. Enhance ClientAppValidator and related tests to exercise token refresh logic. Improve test setup for GraphApiService and fix JWT Base64Url encoding/decoding in AuthenticationService and tests. These changes increase reliability and testability, especially for scenarios involving token revocation or conditional access.
Changed log statements in AuthenticationService from Information to Debug to reduce log verbosity. Added a unit test to ensure forceRefresh bypasses the token cache in MicrosoftGraphTokenProvider.
gwharris7
approved these changes
Mar 27, 2026
ajmfehr
approved these changes
Mar 27, 2026
src/Microsoft.Agents.A365.DevTools.Cli/Services/AuthenticationService.cs
Show resolved
Hide resolved
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Users on corporate networks with TLS inspection proxies (Zscaler, Netskope)
intermittently saw ConnectionResetError (10054) during 'a365 setup all'. The
failure was non-deterministic — different steps each run, restarting sometimes
helped.
Root cause: all token acquisition called 'az account get-access-token' as a
subprocess. The Azure CLI is Python-based and uses an HTTP connection pool that
the TLS proxy would reset mid-execution during longer commands.
Fix has two layers:
Token acquisition: replaced all subprocess calls with direct MSAL.NET via
AuthenticationService. On Windows, MSAL uses WAM — an OS-level broker that
communicates over IPC, bypassing the proxy entirely. On macOS/Linux, MSAL
uses browser or device code flow.
API call resilience: ARM and Graph HTTP calls are now wrapped with
RetryHelper. If the proxy resets the actual API call (not the token), the
retry succeeds without user intervention — automating the "restart and it
works" workaround users were applying manually.
Additional changes:
az CLI is not available
Closes #321